//
// FACE.DAT file format
//
// Author: mla (8-Feb-2020)
//

All integers little-endian.

All offsets are in bytes.

All structures are shown in "packed" form, as if there were no padding fields.

The engine requires that all structures below be naturally aligned
(e.g. the file position of a OBJECT_HEADER must be a multiple of four)

FACE.DAT structure
==================

The FACE.DAT archive is a concatenation of blocks. Each block starts on
a CD sector boundary (2048 bytes); if a block does not occupy a whole number
of sectors, then the last sector of the block will be partially filled.

Each radio script specifies in its header the face block used in that script;
faces outside that block cannot be used (e.g. if only Snake and Campbell are
in the face block, then an attempt to show Otacon's face will crash the engine)

There is no "directory" or "file table" or anything; the radio script
refers to face blocks directly by specifying the sector address and sector
count of the desired face block.

Block
=====

A block is a collection of objects. Each object has a 16-bit ID which is
used by the radio script to select faces, animations, etc...
(e.g. "show face 0x1234").

\It is very probable that the ID is really a 16-bit hash code.\

A block only contains the faces and animations used by the particular
radio script. If the script attempts to use a face that is not present in the
face block, then the engine will crash.

The block header is:

    struct BLOCK_HEADER:
        uint32_t ObjectCount
        OBJECT_HEADER ObjectHeaders[ObjectCount]

The OBJECT_HEADER contains the type, location and ID of an object in the
block:

    struct OBJECT_HEADER:
        uint16_t Type
        uint16_t Id
        uint32_t Size
        uint32_t Offset

    - `Type` is the object type (0=face, 1=animation)

    - `Id` is the object ID (probably a hash code)

    - `Size` is the size of the object, in bytes

    - `Offset` is the offset to the object data, relative to the
      first OBJECT_HEADER in the block header
      (e.g. ``Data = Offset + (char *) &Block->ObjectHeaders[0]``)

      Note this points to either a FACE_DATA or an ANIMATION_DATA structure.

There are two types of objects: faces and animations.

Faces (object type 0)
=====================

A face contains a palette, a "base" image, and up to six "variation" images.
Faces are rendered by blitting the base image, then overlaying any
active variations.

The variations are used for changing the mouth and eyes of the base image.
Variations are automatically selected from the VOX stream lip sync data.

Note that not all variations need be present in a face.

The face data:

    struct FACE_DATA:
        uint32_t PaletteOffset
        uint32_t BaseOffset
        uint32_t VariationOffsets[6]

    All offsets are relative to the start of the FACE_DATA structure.
    A zero offset means the respective entry is missing.

    - `PaletteOffset` points to the palette and `BaseOffset` points to
      the base image (see ``Palettes and images`` below)

    - `VariationOffsets` point to the variation images.
      These are always arranged in a particular order:

        VariationsOffsets[0]        Eyes 1
        VariationsOffsets[1]        Eyes 2
        VariationsOffsets[2]        Not used
        VariationsOffsets[3]        Mouth 1
        VariationsOffsets[4]        Mouth 2
        VariationsOffsets[5]        Not used

        Maintaining a specific order ensures the VOX data can always
        select the correct variation. Note these are always respected, even
        in "special" faces like the "Otacon comm tower yelling close up" face,
        or the "Meryl looking sideways after being discovered" face.


Animations (object type 1)
==========================

An animation is just a sequence of frames; a frame contains an image, a palette
and timing info.

Note the frame image and/or palette are optional; some frames have no palette
nor image, and are used only for timing.

The animation data:

    struct ANIMATION_DATA:
        uint32_t FrameCount
        ANIMATION_FRAME Frames[FrameCount]

    struct ANIMATION_FRAME:
        uint32_t PaletteOffset
        uint32_t ImageOffset
        uint16_t Info[2]

    All offsets are relative to the start of the ANIMATION_DATA structure.
    A zero offset means the respective entry is missing.

    - `PaletteOffset` points to the palette and `ImageOffset` points to
      the frame image (see ``Palettes and images`` below)

    - `Info` contains the frame timing info.

\The meaning of Info[] is unknown. It is possible that the Info[] info is also
used to trigger sound effects in sync with the animation frames
(e.g. when Meryl takes her mask off)\

Palettes and images
===================

A palette is an array of 256 uint16_t:

    struct PALETTE:
        uint16_t Entries[256]

Each color is in PSX RGB format, 5 bits per channel:

    - least significant 5 bits are red channel
    - next 5 bits are green channel
    - next 5 bits are blue channel

An image (including face base images, variations and frame images) has this
format:

    struct IMAGE:
        uint8_t TargetX
        uint8_t TargetY
        uint8_t SizeX
        uint8_t SizeY
        uint8_t Pixels[SizeX * SizeY]

    `TargetX` and `TargetY` contain the coordinates a variation must be
    blitted at, relative to the base image's top left corner. These are zero
    for frame images and base images.

    `SizeX` and `SizeY` contain the size of the image, in pixels.

    `Pixels` contains the pixel data, in row-major ordering, top-down, with
    no particular row alignment. Each entry is an index into some palette
    (e.g. if the image is a face base image, then the entry is an index
    into the face palette)
